import numpy as np
import cv
import scipy.ndimage as ndi

def compute_convex_hull(points) :
    storage = cv.CreateMemStorage(0)
    hull = cv.ConvexHull2 (points, storage, cv.CV_CLOCKWISE, 1)
    return hull 
def get3DHull_xy(img):
    """given a numpy array img return the convex hull"""
  
    # = np.where(iimg>0,1,0).astype(np.uint8)
    newImg = np.zeros(img.shape,np.uint8)
    for k in xrange(newImg.shape[0]):
        ns = np.where(img[k, :, :]>0) 
        if len(ns[0]) > 0 :  
            ns = np.transpose(ns)
            hull = list(compute_convex_hull(ns)) 
            points = np.zeros((newImg.shape[2], newImg.shape[1]), np.uint8)
            points = cv.fromarray(points)
            cv.FillConvexPoly(points, hull, 1)
            points = np.transpose(np.asarray(points))
            newImg[k, :,:] = points
            
    return newImg

def get3DHull_xz(iimg):
    """given a numpy array img return the convex hull"""
  
    img = np.where(iimg>0,1,0).astype(np.uint8)
    newImg = np.zeros(img.shape,np.uint8)
    for k in xrange(newImg.shape[1]):
        ns = np.where(img[ :,k, :]>0) 
        if len(ns[0]) > 0 :  
            ns = np.transpose(ns)
            hull = list(compute_convex_hull(ns)) 
            points = np.zeros((newImg.shape[2], newImg.shape[0]), np.uint8)
            points = cv.fromarray(points)
            cv.FillConvexPoly(points, hull, 1)
            points = np.transpose(np.asarray(points))
            newImg[:,k,:] = points
            
    return newImg

def get3DHull_yz(iimg):
    """given a numpy array img return the convex hull"""
  
    img = np.where(iimg>0,1,0).astype(np.uint8)
    newImg = np.zeros(img.shape,np.uint8)
    for k in xrange(newImg.shape[2]):
        ns = np.where(img[ :, :,k]>0) 
        if len(ns[0]) > 0 :  
            ns = np.transpose(ns)
            hull = list(compute_convex_hull(ns)) 
            points = np.zeros((newImg.shape[1], newImg.shape[0]), np.uint8)
            points = cv.fromarray(points)
            cv.FillConvexPoly(points, hull, 1)
            points = np.transpose(np.asarray(points))
            newImg[:,:,k] = points
            
    return newImg

def get3DHull(img):
    return np.logical_or(get3DHull_yz(img),np.logical_or(get3DHull_xz(img),get3DHull_xy(img)))